package implementation.menu {
import flash.geom.Rectangle;

import palf.commands.Command;
import palf.commands.CommandFactory;
import palf.Gallery;
import palf.visualEffects.layout.Layout;
import palf.visualEffects.layout.LayoutFactory;
import palf.visualEffects.timing.Timing;
import palf.visualEffects.timing.TimingFactory;
import palf.visualEffects.transitions.Transition;

internal class MenuContentCommands {

	private const LAYOUT_FACTORY : LayoutFactory = new LayoutFactory();
	private const TIMING_FACTORY : TimingFactory = new TimingFactory();
	private const COMMAND_FACTORY : CommandFactory = new CommandFactory();

	private var bounds : Rectangle = new Rectangle(40, 40, 400, 400);
	private var gallery : Gallery;
	private var last_layout : Layout;
	private var last_timing : Timing;

	public function MenuContentCommands(gallery : Gallery) {
		this.gallery = gallery;
		this.last_timing = TIMING_FACTORY.getTweenLiteTransition(0.6);
		circleLayout(16, 0).execute();
	}

	private function makeMacro(layout : Layout = null, timing : Timing = null) : Command {
		var commands : Vector.<Command> = Vector.<Command>([]);
		if (layout) {
			var set_layout : Command = setLocalLayoutCommand(layout);
			commands.push(set_layout);
		}
		if (timing) {
			var set_timing : Command = setLocalTimingCommand(timing);
			commands.push(set_timing);
		}
		commands.push(buildTransitionCommand());
		return COMMAND_FACTORY.createMacroCommand(commands);
	}

	private function setLocalLayoutCommand(layout : Layout) : Command {
		var func : Function = function(layout : Layout) : void {
			last_layout = layout;
		};
		return COMMAND_FACTORY.run(func, [layout]);
	}

	private function setLocalTimingCommand(timing : Timing) : Command {
		var func : Function = function(timing : Timing) : void {
			last_timing = timing;
		};
		return COMMAND_FACTORY.run(func, [timing]);
	}

	private function buildTransitionCommand() : Command {
		var func : Function = function() : void {
			var transition : Transition = new Transition(last_layout, last_timing);
			COMMAND_FACTORY.applyEffectToGallery(gallery, transition).execute();
		};
		return COMMAND_FACTORY.run(func);
	}

	public function defaultLayout() : Command {
		var layout : Layout = LAYOUT_FACTORY.getDefaultLayout(bounds);
		return makeMacro(layout);
	}

	public function gridLayout(row : uint, col : uint) : Command {
		var layout : Layout = LAYOUT_FACTORY.getGridLayout(bounds, row, col);
		return makeMacro(layout);
	}

	public function pointLayout() : Command {
		var layout : Layout = LAYOUT_FACTORY.getPointLayout(bounds);
		return makeMacro(layout);
	}

	public function randomLayout() : Command {
		var layout : Layout = LAYOUT_FACTORY.getRandomLayout(bounds);
		return makeMacro(layout);
	}

	public function verticalStackLayout(padding : Number) : Command {
		var layout : Layout = LAYOUT_FACTORY.getVerticalStackLayout(bounds, padding);
		return makeMacro(layout);
	}

	public function coverflowLayout() : Command {
		var layout : Layout = LAYOUT_FACTORY.getCoverflowLayout(bounds);
		return makeMacro(layout);
	}

	public function carouselLayout() : Command {
		var layout : Layout = LAYOUT_FACTORY.getCarouselLayout(bounds);
		return makeMacro(layout);
	}

	public function circleLayout(positions : int, revolutions : int) : Command {
		var layout : Layout = LAYOUT_FACTORY.getCircleLayout(bounds, positions, revolutions);
		return makeMacro(layout);
	}

	public function rowLayout(alignment_ratio : Number, padding : Number) : Command {
		var layout : Layout = LAYOUT_FACTORY.getRowLayout(bounds, alignment_ratio, padding);
		return makeMacro(layout);
	}

	public function columnLayout(alignment_ratio : Number, padding : Number) : Command {
		var layout : Layout = LAYOUT_FACTORY.getColumnLayout(bounds, alignment_ratio, padding);
		return makeMacro(layout);
	}

	public function defaultTiming() : Command {
		var timing : Timing = TIMING_FACTORY.getDefaultTransition();
		return makeMacro(null, timing);
	}

	public function tweenTiming(duration : Number) : Command {
		var timing : Timing = TIMING_FACTORY.getTweenLiteTransition(duration);
		return makeMacro(null, timing);
	}

	public function delayedTiming(duration : Number, delay : Number) : Command {
		var timing : Timing = TIMING_FACTORY.getDelayedTransition(duration, delay);
		return makeMacro(null, timing);
	}

	public function stepTiming(duration : Number, count : int) : Command {
		var timing : Timing = TIMING_FACTORY.getStepTransition(duration, count);
		return makeMacro(null, timing);
	}

	public function delayedStepTiming(duration : Number, count : int, delay : Number) : Command {
		var timing : Timing = TIMING_FACTORY.getDelayedStepTransition(duration, delay, count);
		return makeMacro(null, timing);
	}

}

}
